package com.simba.server.controllers.impl;

import java.sql.Timestamp;

import com.simba.server.commands.impl.fetch.FetchPacketByBoxCodeCmd;
import com.simba.server.commands.impl.record.RecordBoxPackCmd;
import com.simba.server.commands.impl.update.RenewBoxPackCmd;
import com.simba.server.commands.impl.web.WebPackSlotCmd;
import com.simba.server.commands.impl.web.WebSlotStatusCmd;
import com.simba.server.components.CommandExecutor;
import com.simba.server.components.data.BoxInfo;
import org.apache.log4j.Logger;



import com.simba.common.log.LogUtil;

import com.simba.server.components.SlotManager;
import com.simba.server.components.SortCommonDefines;
import com.simba.server.components.SortProtocolCreator;
import com.simba.server.components.data.SlotInfo;
import com.simba.server.controllers.ISlotPackController;

public class SlotPackController implements ISlotPackController
{
	private static final Logger logger = Logger.getLogger(SlotPackController.class);

	@Override
	public void onSlotPackMessage(SlotInfo slotInfo)
	{
		if (slotInfo == null) return;

		if (!slotInfo.getIsPacking().compareAndSet(false, true))
		{
			//原子锁
			LogUtil.LogError(SlotPackController.logger, "This slot is packing now: [" + slotInfo.getSlotId() + "]");
			return;
		}

		doSlotPack(slotInfo);

		slotInfo.getIsPacking().set(false);
	}

	private void doSlotPack(SlotInfo slotInfo) {
		Boolean res = false;
		try
		{
			slotInfo.setLockStatus(SortCommonDefines.SLOT_SOFT_LOCK_FLAG);
			SlotManager.getInstance().setSlotSoftLockStatus(slotInfo);
			SlotManager.getInstance().sendSlotSoftLockToPLC(slotInfo);

			CommandExecutor.executorWebCommand(WebSlotStatusCmd.NAME, slotInfo,false);

			this.printSlotPackPoint("start", slotInfo);

			/**
			 * 收容口不打印包牌
			 */
			res = SlotManager.getInstance().checkSlotIsTrash(slotInfo.getSlotId());
			if (res)
			{
				slotInfo.setCurrentMailCount(0);
				return;
			}

			/**
			 * 指定格口不打包上传
			 */
			if (slotInfo.getSlotWhetherUpload() != 0)
			{
				LogUtil.LogDebug(SlotPackController.logger,
						"This Slot Shouldn't Pack : [" + slotInfo.getSlotId() + "]");
				this.printSlotPackPoint("end", slotInfo);

				slotInfo.resetBoxInfo();
				return;
			}

			String boxCode = slotInfo.getBoxInfo().getBoxCode();
			if (boxCode == null || boxCode.equals(""))
			{
				LogUtil.LogDebug(SlotPackController.logger,
						"Slot Box Code Is Null : [" + slotInfo.getSlotId() + "]");
				slotInfo.setCurrentMailCount(0);
				return;
			}

			res = CommandExecutor.executorSqlCommand(FetchPacketByBoxCodeCmd.NAME, slotInfo.getBoxInfo(),false);
			if (!res)
			{
				LogUtil.LogDebug(SlotPackController.logger,
						"Query Packet Off Count In SlotPackProcess Failed ");
				SlotManager.getInstance().offerSlotPackToRestore(slotInfo);
				return;
			}

			/**
			 * 0 落格不打印包牌,没有正确下落的，不上传
			 */
			if (slotInfo.getBoxInfo().getMails().size() == 0)
			{
				LogUtil.LogDebug(SlotPackController.logger, "Query Packet Off Count is Zero");
				slotInfo.setCurrentMailCount(0);
				return;
			}


			BoxInfo boxInfo = slotInfo.getBoxInfo();
			/*boxInfo.setPlanId(boxInfo.getMails().get(0).getPlanId());
			boxInfo.setRoadSlot(boxInfo.getMails().get(0).getRoadSlot());*/
			boxInfo.setRoadSlot(slotInfo.getArriveName());

			Timestamp createTime = SortProtocolCreator.getInstance().createCurrentTimeStamp();
			slotInfo.getBoxInfo().setCreateTime(createTime.toString());

			res = CommandExecutor.executorSqlCommand(RecordBoxPackCmd.NAME, slotInfo,false);
			if (!res)
			{
				this.retrySlotBoxPack(slotInfo);
				LogUtil.LogDebug(SlotPackController.logger,
						"Insert Slot Pack Record In SlotPackController Failed ");
				SlotManager.getInstance().offerSlotPackToRestore(slotInfo);
				return;
			}


			int uploadNum = slotInfo.getBoxInfo().getUploadNum() + 1;
			slotInfo.getBoxInfo().setUploadNum(uploadNum);
			slotInfo.getBoxInfo().setUploadFlag(1);
//			slotInfo.getBoxInfo().setBoxType("success");

			res = CommandExecutor.executorWebCommand(WebPackSlotCmd.NAME, slotInfo.getBoxInfo(),false);
			if (!res)
			{
				LogUtil.LogDebug(SlotPackController.logger, "Upload Slot Pack To Remote Failed ");
				slotInfo.getBoxInfo().setUploadFlag(0);
//				slotInfo.getBoxInfo().setBoxType("remote failed");
			}

			CommandExecutor.executorSqlCommand(RenewBoxPackCmd.NAME, slotInfo.getBoxInfo(),false);

			this.printSlotPackPoint("end", slotInfo);

			slotInfo.resetBoxInfo();
		}
		catch (Exception ex)
		{
			LogUtil.LogError(SlotPackController.logger,
					"Handle Slot Pack Message In SlotPackController Error -- Exception : " + ex);
		}
	}

	private void printSlotPackPoint(String point, SlotInfo slotInfo)
	{
		StringBuilder boxInfoBuilder = new StringBuilder(50);
		boxInfoBuilder.append("[SlotPackController.onSlotPackMessage] Slot:[");
		boxInfoBuilder.append(slotInfo.getSlotId());
		boxInfoBuilder.append("],Pack Box Code:[");
		boxInfoBuilder.append(slotInfo.getBoxInfo().getBoxCode());
		boxInfoBuilder.append("],mailCount:[");
		boxInfoBuilder.append(slotInfo.getBoxInfo().getMails().size());
		boxInfoBuilder.append("],point:[");
		boxInfoBuilder.append(point);
		boxInfoBuilder.append("]");
		LogUtil.LogDebug(SlotPackController.logger, boxInfoBuilder.toString());
	}

	private void retrySlotBoxPack(SlotInfo slotInfo)
	{

	}

}
